package com.zust.zst.controller.login;

import cn.dev33.satoken.stp.StpUtil;
import com.dxy.library.json.gson.GsonUtil;
import com.zust.zst.aop.HttpAuthChecker;
import com.zust.zst.common.dto.LoginDTO;
import com.zust.zst.common.vo.ResultVO;
import com.zust.zst.common.vo.login.LoginVO;
import com.zust.zst.dao.entity.Teacher;
import com.zust.zst.dao.entity.Student;
import com.zust.zst.service.LoginService;
import com.zust.zst.token.GlobalTokenManagement;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.validation.Valid;

/**
 * @author gavin
 * @date 2022/11/13 17:20
 */
@RestController
@Api(tags = "管理员、教师登录接口")
@Slf4j
@Validated
public class LoginController {

    private static final int STUDENT = 3;

    @Resource(name = "loginServiceImpl")
    private LoginService loginService;

    @PostMapping("/admin/login")
    @ApiOperation(value = "管理员/讲师登录验证")
    public ResultVO<LoginVO> adminLogin(@RequestBody @Valid LoginDTO teacherLoginRequest) {
        // 先找token，有token则拒绝二次登录
        if (GlobalTokenManagement.tokenMap.containsKey(StpUtil.getTokenValue())) {
            return ResultVO.error("已登录");
        }
        Teacher teacher = loginService.teacherLogin(teacherLoginRequest.getUid(), teacherLoginRequest.getPassword(), teacherLoginRequest.getType());
        if (teacher != null) {
            // sa-token接管登录
            StpUtil.login(teacherLoginRequest.getUid());

            LoginVO loginVO = LoginVO.builder().
                    uid(teacherLoginRequest.getUid())
                    .username(teacher.getName())
                    .type(teacherLoginRequest.getType())
                    .token(StpUtil.getTokenValue())
                    .build();

            // token半持久化（后期应改用redis/mysql替代）
            GlobalTokenManagement.tokenMap.put(StpUtil.getTokenValue(), loginVO);
            log.info("登录成功: {}", loginVO);
            return ResultVO.success(loginVO);
        }

        log.warn("登录失败: {}", teacherLoginRequest);
        return ResultVO.error("用户名或密码错误!");
    }

    @PostMapping("/student/login")
    @ApiOperation(value = "学生登录验证")
    public ResultVO<LoginVO> studentLogin(@RequestBody @Valid LoginDTO studentLoginRequest) {
        // 先找token，有token则拒绝二次登录
        if (GlobalTokenManagement.tokenMap.containsKey(StpUtil.getTokenValue())) {
            return ResultVO.error("已登录");
        }
        Student student = loginService.studentLogin(studentLoginRequest.getUid(), studentLoginRequest.getPassword());
        if (student != null) {
            // sa-token接管登录
            StpUtil.login(studentLoginRequest.getUid());

            LoginVO loginVO = LoginVO.builder().
                    uid(studentLoginRequest.getUid())
                    .username(student.getName())
                    .type(STUDENT)
                    .token(StpUtil.getTokenValue())
                    .build();

            // token半持久化（后期应改用redis/mysql替代）
            GlobalTokenManagement.tokenMap.put(StpUtil.getTokenValue(), loginVO);
            log.info("登录成功: {}", loginVO);
            return ResultVO.success(loginVO);
        }

        log.warn("登录失败: {}", studentLoginRequest);
        return ResultVO.error("用户名或密码错误!");
    }

    @PostMapping("/logout")
    @ApiOperation(value = "管理员/老师退出登录")
    @HttpAuthChecker
    public ResultVO adminLogout(@RequestBody String token) {
        // 解析json中的token
        String curToken = GsonUtil.getAsString(token, "token");
        if (curToken != null && !"".equals(curToken)) {
            log.info("删除token: {}", curToken);
            log.info("退出登录: {}", GlobalTokenManagement.tokenMap.get(curToken));
            GlobalTokenManagement.tokenMap.remove(curToken);
            StpUtil.logout();
            return ResultVO.success("已退出登录", "");
        } else {
            log.warn("遇到非法的退出登录");
            return ResultVO.error("遇到非法的退出登录");
        }
    }
}

